<template>
  <div class="all" @click="closeO">
  <div :style="{ width: leftWidth }">
    <div style="display: flex; padding: 10px 0" class="pickers">
      <div style="margin-right: 10px">
        <el-switch v-model="horizontal"></el-switch> {{ horizontal? "横向": "纵向" }}
      </div>
      <div style="margin-right: 10px">
        <el-switch v-model="collapsable"></el-switch> {{ collapsable? "可收起": "仅展开" }}
      </div>
      <div  style="margin-right: 10px">
        <el-switch v-model="showvalue" @change="handleshownodeval"></el-switch> {{ showvalue? "显示节点值": "不显示节点值" }}
      </div>
      <div style="margin-right: 10px" v-show="!boolCal">
        <el-switch v-model="disaled"></el-switch> {{ disaled? "禁止编辑": "可编辑" }}
      </div>
      <div style="margin-right: 10px">
        <el-switch v-model="onlyOneNode"></el-switch> {{ onlyOneNode? "仅拖动当前节点": "拖动当前节点树" }}
      </div>
      <div style="margin-right: 10px">
        <el-switch v-model="cloneNodeDrag"></el-switch> {{ cloneNodeDrag? "拖动节点副本": "拖动节点本身" }}
      </div>
    </div>
    <div style="padding-bottom: 10px" class="pickers">
      背景色：
      <el-color-picker v-model="style.background" size="small"></el-color-picker>&nbsp; 文字颜色：
      <el-color-picker v-model="style.color" size="small"></el-color-picker>&nbsp;
      搜索：
      <input type="text" v-model="keyword" placeholder="请输入搜索内容" @keydown.enter="filter" />
            <el-button v-show="!boolCal" style="margin: 0 10px" type="primary" plain @click="saveTree">保存</el-button>
      <!--            <el-button style="margin: 0 10px" type="primary" plain @click="showMe">查看树</el-button>-->
    </div>
    <div class="lll">
      <div ref="nodeOne" class="nodeOne">
        <zm-tree-org ref="tree" :data="data" :disabled="disaled" :horizontal="horizontal" :collapsable="collapsable"
          :label-style="style" :node-draggable="true" :default-expand-level="1" :only-one-node="onlyOneNode"
          :clone-node-drag="cloneNodeDrag" :node-draging="nodeDragMove" :node-drag-end="nodeDragEnd" :toolBar="toolBar"
          :filterNodeMethod="filterNodeMethod" @on-contextmenu="onMenus" @on-expand="onExpand"
          @on-node-click="onNodeClick" @on-node-dblclick="onNodeDblclick" @on-node-copy="onNodeCopy"
          :define-menus="menus" :nodeAdd="handleNodeAdd" :nodeDelete="onDeleteNode">
          <!-- 自定义节点内容 -->
          <template slot-scope="{node}">
            <div class="tree-org-node__text node-label node" @contextmenu.prevent="terFun(node)">
              {{ node.label }}
              <div v-if="treeScope && !node.disabled && node.open" class="late" id="lateId">
                <el-input type="textarea" placeholder="请输入内容" v-model="cardOne.label" maxlength="30" show-word-limit>
                </el-input>
                <div @click="close(cardOne)" class="onCloseCss">确定</div>
              </div>
            </div>

          </template>
          <!-- 自定义展开按钮 -->
          <template v-slot:expand="{ node }">
            <div>{{ node.children.length }}</div>
          </template>
        </zm-tree-org>
      </div>
    </div>
  </div>
  <div id="popover">
    <div class="content-box">
      <div class="content-box-header">
        <p>节点属性：</p>
        <button class="close-button" @click="closeAttribute"><img src="../../icons/png/close.png"></button>
      </div>
      <div class="content-box-body" v-html="attribute"></div>
    </div>
  </div>
  <div v-show="pop" :style="{ width: rightWidth }">
    <el-form label-width="120px">
      <div v-show="!boolOp">
      <el-form-item label="节点名称">
        <el-col :span="8">
        <el-input v-model="curname" />
      </el-col>
      </el-form-item>
      <el-form-item label="节点类型">
        <el-col :span="8">
        <el-input v-model="curtype" />
      </el-col>
      </el-form-item>
      <el-form-item label="节点权重">
        <el-col :span="8">
        <el-input
        oninput ="value=value.replace(/[^0-9.]/g,'')"
        v-model="curweight" />
      </el-col>
      </el-form-item>
      <el-form-item label="指标值">
        <el-col :span="8">
        <el-input
        oninput ="value=value.replace(/[^0-9.]/g,'')"
        v-model="curval" />
      </el-col>
      </el-form-item>
      </div>

      <el-form-item label="算子" v-show="boolOp">
        <el-radio-group v-model="param">
          <el-radio label="+">加</el-radio>
          <el-radio label="-">减</el-radio>
          <el-radio label="*">乘</el-radio>
          <el-radio label="/">除</el-radio>
          <el-radio label="avg">平均值</el-radio>
          <el-radio label="max">最大值</el-radio>
          <el-radio label="min">最小值</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="saveChanges">保存</el-button>
        <el-button @click="onCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
  </div>
</template>

<script>
import index from '@/components/Breadcrumb/index.vue';
import treeApi from '@/api/treeManage'
import { getToken } from '@/utils/auth'
import { tSConstructorType } from '@babel/types';
import { constantRoutes } from '@/router';
export default {
  components: { index },
  data() {
    return {
      toolBar: {
        scale: false,
      },
      keyword: "",
      menus: [{ name: '复制文本', command: 'copy' }, { name: '新增节点', command: 'add' }, { name: '编辑节点', command: 'edit1' }, { name: '删除节点', command: 'delete' }],
      data: {},
      horizontal: false,
      collapsable: true,
      showvalue: false,
      onlyOneNode: false,//仅拖动当前节点
      cloneNodeDrag: false,//是否拷贝节点拖拽 false仅拖拽  true拷贝+保留原位
      expandAll: true,
      disaled: false,
      style: { color: "#fff", background: "#108ffe" },
      treeScope: false,
      redirect: undefined,
      leftWidth: '100%', // 树展示页面的宽度，初始值为页面长度的 100%
      rightWidth: '0%', // 编辑节点的表单宽度，初始值为页面长度的 0%
      //弹窗
      pop: false,
      //当前树名
      treename:"",
      //card组件信息
      cardOne: {},
      curnode: {},            // 当前节点
      curname:"",             // 当前节点名
      curtype:"",             // 当前节点类型
      curweight:0.0,          // 当前节点权重
      curval:0.0,             // 当前节点指标值
      param:'1',              // 算子选择
      id:0,                   // 节点id
      attribute: "",          // 节点属性

      //由树管理页面跳转,若由前一个页面跳转，则boolSkip为true
      tid:0,
      boolSkip:false,
      //由导入数据后跳转
      boolCal:false,
      //由算子管理跳转
      boolOp:false
    };
  },
  created() {

    // 从globalData中恢复数据或给初值(如果data没有name属性，即初始化给值)
    let savedData = this.$globalData.treedata
    if (savedData.name) {
      this.data = savedData
      this.getmaxid(this.data)
    }else{
      this.$set(this.data, 'id', 0)
      this.$set(this.data, 'weight', 1)
      this.$set(this.data, 'val', 0)
      this.$set(this.data, 'name', '根节点')
      this.$set(this.data, 'label', '根节点')
      this.$set(this.data, 'type', 'nodeType')
    }

    // 若由算子管理界面的修改按钮跳转，则获取传递过来的数据
    if (this.$route.params.boolOp!=null) {
      this.tid = this.$route.params.tid
      this.boolOp = this.$route.params.boolOp
      treeApi.getTreeById(this.tid).then( response => {
          this.data = response.data.tree;
          this.getmaxid(this.data)
      });
    }

    // 若由数据管理界面的修改按钮跳转，则获取传递过来的数据
    if (this.$route.params.boolSkip!=null) {
      this.tid = this.$route.params.tid
      this.boolSkip = this.$route.params.boolSkip
      treeApi.getTreeById(this.tid).then( response => {
          this.data = response.data.tree;
          this.getmaxid(this.data)
      });
    }
    // 若由数据管理界面的导入按钮跳转，则获取传递过来的数据,且当前树不可编辑
    if (this.$route.params.boolCal!=null) {
      this.data = this.$route.params.tree
      this.boolCal = this.$route.params.boolCal
      this.disaled = true
      //该message与后端发送的message对应
      if(this.$route.params.message=='导入成功!'){
        this.$message({
          message: '指标树计算完成！',
          type: 'success'
        })
      }else{
        this.$message({
          message: this.$route.params.message,
          type: 'error'
        })
      }

    }

    this.treename=this.data.treename
  },
  mounted() {
    this.$router.beforeEach((to, from, next) => {
      // 在每次路由切换前保存数据
      this.$globalData.treedata=this.data
      if(to.name=='login'){
        this.$globalData.treedata={}
        this.data={}
      }
      next()
      
    })
    
  },
  methods: {
    handleshownodeval(){
      this.shownodeval(this.data)
    },
    shownodeval(node){
      if (!node.children) {
        this.$set(node, 'children', []);
      }
      if(!node.name){
        return false;
      }
      if(this.showvalue){
        node.label=node.name+"("+node.val+")"
      }else{
        node.label=node.name
      }
      for (let i = 0; i < node.children.length; i++) {
        this.shownodeval(node.children[i])
      }
      return true;
    },
    onDeleteNode(node) {
      console.log("删除节点")
      // 弹出确认框
      this.$confirm("确定要删除该节点及其子节点吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        this.deletenode(this.data,node.id)
      }).catch(() => {
          // 用户点击了取消按钮，不执行删除操作
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    deletenode(node,id){
      //若是叶子节点，在父节点已判断完成，无需递归
      if(!node.children) return false;

      for (let i = 0; i < node.children.length; i++) {
        if (node.children[i].id==id){
          node.children.splice(i, 1);
          return true;
        }else{
          this.deletenode(node.children[i],id)
        }
      }
    },
    getmaxid(data){
      if (data.id>this.id) {
        this.id=data.id
      }
      let children=data.children
      if (Array.isArray(children)) {
        children.forEach((item) => {
          this.getmaxid(item);
        });
      }
    },
    saveChanges() {
      this.$message({
          message: '编辑已保存！',
          type: 'success'
        })
      // 填写正确
      this.$set(this.curnode,"label",this.curname);
      this.curnode.name=this.curname;         //节点名
      this.curnode.type = this.curtype;       // 节点类型
      this.curnode.weight=this.curweight;     //节点权重
      this.curnode.val=this.curval;                //节点指标值
      this.curnode.param = this.param;
      this.pop=false;
      this.leftWidth = '100%';
      this.rightWidth = '0%';
    },
    onCancel() {
        this.pop = false;
        this.leftWidth = '100%';
        this.rightWidth = '0%';
        this.$message({
          message: '编辑已取消！',
          type: 'warning'
        })
    },
    //动态赋值
    terFun(node) {
      if (node.disabled || this.disaled) { this.menus = [{ name: '复制文本', command: 'copy' }] } else {
        this.menus = [{ name: '复制文本', command: 'copy' }, { name: '新增节点', command: 'add' }, { name: '编辑节点', command: 'edit1' }, { name: '删除节点', command: 'delete' }]
      }
    },
    //右侧菜单点击事件
    onMenus({ node, command }) {
      //自定义编辑--弹窗编辑
      if (command === 'edit1' && !node.disabled) {

        this.pop = true;
        this.leftWidth = '70%';
        this.rightWidth = '30%';

        this.curnode=node;
        this.curname=this.curnode.label;         //节点名
        this.curtype = this.curnode.type;
        this.curweight=this.curnode.weight;     //节点权重
        this.curval=this.curnode.val;                //节点指标值
        this.param=this.curnode.param;                 //算子选择
        //当前不允许编辑
      } else if (node.disabled && command === 'edit1') {
        this.$message({
          type: 'info',
          message: '当前内容不可编辑'
        });
        //自定义编辑--card
      } else if (command === 'edit1' && !this.pop && !node.disabled) {
        this.$set(node, 'open', true)
        this.cardOne = node
        this.treeScope = true
      };
    },
    //自定义修改属性值
    editFun(data, node, val) {
      if (!data || !data.length) {
        return;
      }
      for (let i = 0; i < data.length; i++) {
        if (data[i].id === node.id) {
          data[i].label = val;
          break;
        }
        this.editFun(data[i].children, node, val);
      }
    },
    //确定 关闭car界面
    close(val) {
      this.$delete(val, 'open')
      this.treeScope = false
    },
    //颠倒编辑外区域，关闭
    closeO(event) {
      var currentCli = document.getElementById("lateId");
      if (currentCli) {
        if (!currentCli.contains(event.target)) {
          this.treeScope = false;
        }
      }
    },
    //自定义card显示
    filter() {
      this.$refs.tree.filter(this.keyword);
    },
    filterNodeMethod(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    //展开事件
    onExpand(e, data) {
    },
    nodeDragMove(data) {
    },
    nodeDragEnd(data, isSelf) {
      // isSelf && this.$Message.info("移动到自身");
    },
    //点击节点
    onNodeClick(e, data) {
      // this.$Message.info(data.label);
      var popover = document.getElementById("popover");
      if (popover.style.display === "block"){
        popover.style.display = "none";
        // console.log("隐藏")
      }
      else {
        popover.style.display = "block";
        // console.log("显示");
      }
      // console.log("x:" + e.screenX);
      // console.log("y:" + e.screenY);
      popover.style.left = e.screenX + "px";
      popover.style.top = e.screenY - 100 + "px";
      // console.log("onNodeClick")
      this.attribute = "节点id: " + data.id + "<br>节点名称: " + data.name + "<br>节点类型: " + data.type + "<br>节点指标值: " + data.val + "<br>节点权重: " + data.weight;
      // console.log(data.param)
      if (!data.children) {
        this.$set(data, 'children', []);
      }
      if (data.children.length != 0) {
        this.attribute += "<br>节点算子: " + data.param;
      }
    },
    closeAttribute() {
      var popover = document.getElementById("popover");
      popover.style.display = "none";
    },
    onNodeDblclick() {
      // this.$Message.info("双击节点");
    },
    onNodeCopy() {
      // this.$Message.success("复制成功");
    },
    handleNodeAdd(node) {
      if (!node.children) {
        this.$set(node, 'children', []);
      }
        this.id++;
        var newchild={};
        newchild.pid=node.id;
        newchild.id=this.id;
        newchild.idflag=true;
        newchild.label="新增节点" + newchild.id;
        newchild.name= newchild.label;
        newchild.type="";
        newchild.weight=1.0;
        newchild.val=0.0;
        newchild.param = "";
        node.children.push(newchild);
//         console.log(node);
      this.$message({
                type: 'success',
                message: '添加成功！'
            });
    },
    expandChange() {
      this.toggleExpand(this.data, this.expandAll);
    },
    //递归创建节点树
    toggleExpand(data, val) {
      if (Array.isArray(data)) {
        data.forEach((item) => {
          this.$set(item, "expand", val);
          if (item.children) {
            this.toggleExpand(item.children, val);
          }
        });
      } else {
        this.$set(data, "expand", val);
        if (data.children) {
          this.toggleExpand(data.children, val);
        }
      }
    },
    checkNodeName(node){
      if (!node.children) {
        this.$set(node, 'children', []);
      }
      if(!node.name){
        return false;
      }
      for (let i = 0; i < node.children.length; i++) {
        if (!this.checkNodeName(node.children[i])) return false;
      }
      return true;
    },
    checkNodeOperator(node){
      if (!node.children) {
        // console.log("没子节点")
        this.$set(node, 'children', []);
      }
      if(node.children.length == 0) return true;
      if (!node.param) return false;
      for (let i = 0; i < node.children.length; i++) {
        if(!this.checkNodeOperator(node.children[i])) return false;
      }
      return true;
    },
    // 首先验证树的合法性，若合法传给后端，不合法提示用户更改
    saveTree() {
      // console.log("saveFunc")
      // console.log(this.data)
      // 所有节点必须具备name
      if (!this.checkNodeName(this.data)) {
        this.$message({
          type: 'error',
          message: '当前树结构不合法! 缺少名称'
        });
        return;
      }
      // 所有父节点必须具备算子
      // if (!this.checkNodeOperator(this.data)) {
      //   this.$message({
      //     type: 'error',
      //     message: '当前树结构不合法! 父节点缺少算子'
      //   });
      //   return;
      // }

      // 发送后端，接受保存结果
      this.$prompt('请输入指标体系树名', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          inputValue: this.treename,

        }).then(({ value }) => {
          this.$set(this.data, 'treename', value);
          this.$set(this.data, 'token', getToken());
          const treedata = this.data;
          this.$store.dispatch('tree/savetree', treedata).then(() => {
            // 若是修改跳转的信息，则需要删除原来的树
              if(this.boolSkip || this.boolOp){
                treeApi.deleteTreeById(this.tid).then( response => {
                  this.$message({
                    type: 'success',
                    message: '修改完成，再次修改请重新进入管理！'
                  });
                  this.data={id: 0,    //组织id，必须
                             label: ""}
                  this.boolSkip=false
                  this.boolOp=false
                })
              }
            this.$message({
              type: 'success',
              message: '保存成功！'
            });
          }).catch(error => {
            this.$message({
              type: 'error',
              message: '保存失败！'
          });
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '取消输入'
          });
        });


    },
    // 接收后端传入数据，展示指标树
    showMe() {
      var orgData = {
        id: 0,    //组织id，必须
        label: "xxx科技有限公司",  //组织名称，必须
        name: "xxx科技有限公司",
        value: 0.0,
        weight: 1.0,
        param: '+',
        disabled: true,   //是否可编辑
        children: [      //子级
          {
            id: 2,    //子级组织id，必须
            pid: 1,   //父级组织id，必须
            label: "产品研发部",   //组织名称，必须
            name: "产品研发部",
            value: 0.0,
            weight: 1.0,
            param: '+',
            expand: false,  //当前节点下的节点是否默认展开
            noDragging: true,  //当前节点是够允许拖拽
            children: []
          }
        ]
      };
      this.data = orgData;
    },

  },
};
</script>
<style scoped>

.all{
  display: flex;
  flex-direction: row;
  align-items: center;
}

.content-box {
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 10px;
}

.content-box-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.content-box-header h2 {
  margin: 0;
}

.content-box-body {
  margin: 0;
}


.close-button {
  position: absolute;
  top: 0;
  right: 0;
  padding: 6px;
  font-size: 16px;
  background-color: transparent;
  color: #555;
  border: none;
  outline: none;
  cursor: pointer;
}

.close-button:hover {
  color: #000;
}


#popover {
  display: none;
  position: absolute;
  z-index: 9999;
  padding: 10px;
  border: 1px solid #ccc;
  background-color: #fff;
  box-shadow: 0px 0px 5px #888;
}



.pickers {
  display: flex;
  justify-content: center;
  margin: 10px;
}

.lll {
  margin: 0 30px;
  border: 2px dashed rgb(141, 140, 140);
  height: 680px;
}

.node {
  position: relative;
}

.nodeOne {
  height: 100%;
}

.late {
  position: absolute;
  top: 20px;
  right: -100px;
  width: 200px;
  min-height: 100px;
  z-index: 999;
  background: #F2E2BE;
  padding: 10px;
}

.onCloseCss {
  width: 50px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  background: #108FFE;
  margin: 10px auto;
  z-index: 999;
}

::v-deep .is-edit {
  background: palegoldenrod !important;
}

.line{
  text-align: center;
}


</style>
